package com.camelot.boot.module.ai.util;

import com.camelot.boot.module.ai.controller.admin.chat.dto.AiResumeTransferDTO;
import com.camelot.boot.module.ai.dal.dataobject.chat.AiResumeTransferDO;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.poi.xwpf.usermodel.*;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.*;

import java.io.FileOutputStream;
import java.math.BigInteger;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

public class DOCXUtil {
    // 列宽配置（百分比，总和应≤60%）
    // 经过多次打印测试验证的优化配置
    private static final int[] COLUMN_WIDTHS = {
            4,   // 姓名列
            4,   // 间隔列
            0,   // 隐藏列（用于布局）
            4,   // 空白信息列

            3,   // 性别列
            1,   // 间隔列

            5,   // 空白信息列
            0,   // 隐藏列

            7,   // 出生日期列
            0,   // 隐藏列

            7,   // 空白信息列
            3,   // 间隔列
            3,   // 空白信息列

            1,   // 间隔列
            6,   // 空白信息列
            9    // 备注列
    }; // 总和=60%

    private static final int[] columnWidths = {  // 自定义每列宽度
            1200,   // 第1列
            1400,  // 第2列
            1000,  // 第3列
            1000,  // 第4列
            1800,  // 第5列
            1000,  // 第6列
            1700    // 第7列
    };

    public static AiResumeTransferDO generate(AiResumeTransferDTO dto) {
        try {
            // 创建一个新的Word文档
            XWPFDocument document = new XWPFDocument();

            // 设置页面为A4大小
            setA4PageSize(document);

            // 创建标题
            createTitle(document, "个人简历表",16);

            ObjectMapper mapper = new ObjectMapper();
            JsonNode jsonNode = mapper.readTree(dto.getText());

            // 创建个人信息表格
            createPersonalInfoTable(document,jsonNode);

            // 创建教育培训经历表格
            createEducationTable(document,jsonNode.get("educationBackground"));

            // 创建工作经历表格
            createWorkExperienceTable(document,jsonNode.get("companies"));

            // 创建项目经验表格
            createProjectExperienceTable(document,jsonNode.get("projectExperience"));

            // 添加公司核实声明
            addVerificationStatement(document);

            String candidateName = jsonNode.get("candidateName").asText();
            String fileName = "个人简历_" + candidateName + "_继远.docx";

            FileOutputStream outputStream = new FileOutputStream(dto.getPath()+"/"+fileName);
            // 保存文档
            document.write(outputStream);

            String mobile = jsonNode.get("mobile").asText();
            String idNumber = jsonNode.get("idNumber").asText();
            AiResumeTransferDO aiResumeTransferDO = new AiResumeTransferDO();
            aiResumeTransferDO.setPath(dto.getPath());
            aiResumeTransferDO.setFileName(fileName);
            aiResumeTransferDO.setOriginFileName(dto.getOriginFileName());
            aiResumeTransferDO.setUserId(dto.getUserId());
            aiResumeTransferDO.setCandidateName(candidateName);
            aiResumeTransferDO.setMobile(mobile);
            aiResumeTransferDO.setIdNumber(idNumber);
            aiResumeTransferDO.setType(1);
            return aiResumeTransferDO;

        } catch (Exception e) {
            System.err.println("生成简历时出错: " + e.getMessage());
            e.printStackTrace();
            return null;
        }
    }

    public static AiResumeTransferDO generateASZ(AiResumeTransferDTO dto){
        try {
            // 创建一个新的Word文档
            XWPFDocument document = new XWPFDocument();

            // 设置页面为A4大小
            setA4PageSize(document);

            // 创建标题
            createTitle(document, "个人简历表",18);

            ObjectMapper mapper = new ObjectMapper();
            JsonNode jsonNode = mapper.readTree(dto.getText());

            // 创建个人信息表格
            createASZPersonalInfoTable(document,jsonNode);

            // 创建教育培训经历表格
            createASZEducationTable(document,jsonNode.get("educationBackground"));
            
            createWorkingSkillsTable(document,jsonNode.get("workingSkills"));
//
            // 创建工作经历表格
            createASZWorkExperienceTable(document,jsonNode.get("companies"));
//
            // 创建项目经验表格
            createASZProjectExperienceTable(document,jsonNode.get("projectExperience"));
//
            // 添加公司核实声明
            addASZVerificationStatement(document);

            String candidateName = jsonNode.get("candidateName").asText();
            String fileName = "个人简历_" + candidateName + "_埃森哲.docx";

            FileOutputStream outputStream = new FileOutputStream(dto.getPath()+"/"+fileName);
            // 保存文档
            document.write(outputStream);

            String mobile = jsonNode.get("mobile").asText();
            String idNumber = jsonNode.get("idNumber").asText();
            AiResumeTransferDO aiResumeTransferDO = new AiResumeTransferDO();
            aiResumeTransferDO.setPath(dto.getPath());
            aiResumeTransferDO.setFileName(fileName);
            aiResumeTransferDO.setOriginFileName(dto.getOriginFileName());
            aiResumeTransferDO.setUserId(dto.getUserId());
            aiResumeTransferDO.setCandidateName(candidateName);
            aiResumeTransferDO.setMobile(mobile);
            aiResumeTransferDO.setIdNumber(idNumber);
            aiResumeTransferDO.setType(2);
            return aiResumeTransferDO;

        } catch (Exception e) {
            System.err.println("生成简历时出错: " + e.getMessage());
            e.printStackTrace();
            return null;
        }
    }

    private static void addASZVerificationStatement(XWPFDocument document) {
        XWPFTable table = document.createTable(2, 7);
        initializeTableCells(table, 2, 7);
        table.setWidth("100%");

        setCellText(table.getRow(0).getCell(0),"填表人",false);
        TableUtil.mergeCellsHorizontally(table, 0, 1, 6);
        setCellText(table.getRow(0).getCell(1),"本人在该表中所填内容均属实，无虚报之处\n\t\t\t填表人签字：   年  月  日",false);

        setCellText(table.getRow(1).getCell(0),"供应商意见",false);
        TableUtil.mergeCellsHorizontally(table, 1, 1, 6);
        setCellText(table.getRow(1).getCell(1),"本公司确认该表所填内容均属实，如有虚报之处，承担由此引起的一切责任。\n\n\n\t\t\t（供应商盖章）      年    月    日",false);
    }

    private static void createASZProjectExperienceTable(XWPFDocument document, JsonNode projectExperience) {
        // 创建项目经历标题行
        XWPFTable table = document.createTable(2, 1);
        initializeTableCells(table, 2, 7);
        table.setWidth("100%");
        XWPFTableRow titleTableRow = table.getRow(0);
        setCellTextBoldAndColor(titleTableRow.getCell(0), "项目经历", true,"C0C0C0");
        titleTableRow.setHeight(600);
        TableUtil.mergeCellsHorizontally(table, 0, 0, 6);


        XWPFTableRow textRow = table.getRow(1);
        Iterator<JsonNode> elements = projectExperience.elements();
        setCellText(textRow.getCell(0), "", false);
        int index = 1;
        while (elements.hasNext()){
            JsonNode next = elements.next();
            appendCellText(textRow.getCell(0),index + "、项目名称",true);
            appendCellText(textRow.getCell(0),next.get("projectName").asText(),true);
            appendCellText(textRow.getCell(0),"项目概述：",false);
            appendCellText(textRow.getCell(0),next.get("projectDesc").asText(),false);
            appendCellText(textRow.getCell(0),"主要职责：",false);
            appendCellText(textRow.getCell(0),next.get("duty").asText(),false);
            appendCellText(textRow.getCell(0),"",false);
            index++;
        }

        titleTableRow.setHeight(600);
        TableUtil.mergeCellsHorizontally(table, 1, 0, 6);
    }

    private static void createASZWorkExperienceTable(XWPFDocument document, JsonNode companies) {
        // 创建工作经历标题行
        XWPFTable table = document.createTable(2, 1);
        initializeTableCells(table, 2, 7);
        table.setWidth("100%");
        XWPFTableRow titleTableRow = table.getRow(0);
        setCellTextBoldAndColor(titleTableRow.getCell(0), "工作经历", true,"C0C0C0");
        titleTableRow.setHeight(600);
        TableUtil.mergeCellsHorizontally(table, 0, 0, 6);

        XWPFTableRow textRow = table.getRow(1);
        Iterator<JsonNode> elements = companies.elements();
        setCellText(textRow.getCell(0),"", false);
        while (elements.hasNext()){
            JsonNode next = elements.next();
            appendCellText(textRow.getCell(0),next.get("startDate").asText() + " - " + next.get("endDate").asText() + "\t\t" + next.get("companyName").asText() + "\n",true);
            appendCellText(textRow.getCell(0),next.get("workDesc").asText() + "\n\n",false);
            appendCellText(textRow.getCell(0),"",false);
        }

        titleTableRow.setHeight(600);
        TableUtil.mergeCellsHorizontally(table, 1, 0, 6);

    }

    private static void createWorkingSkillsTable(XWPFDocument document, JsonNode workingSkills) {
        XWPFTable table = document.createTable(2,7);
        initializeTableCells(table, 2, 7);
        table.setWidth("100%");
        XWPFTableRow titleTableRow = table.getRow(0);
        setCellTextBoldAndColor(titleTableRow.getCell(0), "个人主要技能", true,"C0C0C0");
        titleTableRow.setHeight(600);
        TableUtil.mergeCellsHorizontally(table, 0, 0, 6);

        XWPFTableRow textRow = table.getRow(1);
        setCellText(textRow.getCell(0), workingSkills.asText(), false);
        TableUtil.mergeCellsHorizontally(table, 1, 0, 6);
    }

    private static void createASZEducationTable(XWPFDocument document, JsonNode educationBackground) {
        XWPFTable table = document.createTable(2,7);
        initializeTableCells(table, 2, 7);
        table.setWidth("100%");
        XWPFTableRow titleTableRow = table.getRow(0);
        setCellTextBoldAndColor(titleTableRow.getCell(0), "教育培训经历（包含教育经历、培训经历、证书等）", true,"C0C0C0");
        titleTableRow.setHeight(600);
        TableUtil.mergeCellsHorizontally(table, 0, 0, 6);

        StringBuilder sb = new StringBuilder();
        Iterator<JsonNode> elements = educationBackground.elements();
        while (elements.hasNext()){
            JsonNode next = elements.next();
            JsonNode startDate = next.get("startDate");
            sb.append(startDate.asText());
            sb.append(" - ");
            sb.append(next.get("endDate").asText());
            sb.append("\t\t");
            sb.append(next.get("school").asText());
            sb.append("\t\t");
            sb.append(next.get("major").asText());
            sb.append("\t\t");
            sb.append(next.get("degree").asText());
            sb.append("\t\t");
            sb.append(next.get("degreeType").asText());
            sb.append("\n");
        }
        setCellText(table.getRow(1).getCell(0), sb.toString(), false);
        TableUtil.mergeCellsHorizontally(table, 1, 0, 6);

    }

    private static void createASZPersonalInfoTable(XWPFDocument document, JsonNode jsonNode) {
        // 创建6行16列的表格
        XWPFTable table = document.createTable(4, 7);
// 设置列宽（在初始化单元格之前）

        // 初始化所有单元格，防止null
        initializeTableCells(table, 3, 7);

        // 设置表格宽度为100%页面宽度
        table.setWidth("100%");
        // 设置列宽
        // 设置第一行的列宽（定义表格结构）
        setColumnWidths(table.getRow(0), columnWidths);
        // 设置所有行高为30磅
        for (XWPFTableRow row : table.getRows()) {
            row.setHeight(600); // 30磅 = 600 twips
        }
        // 合并单元格创建表头行
        mergeCellsForASZPersonalInfo(table,jsonNode);

        // 设置表格样式
        setTableBorders(table);

        // 填充个人信息表格内容
        fillASZPersonalInfoTable(table);
    }

    private static void fillASZPersonalInfoTable(XWPFTable table) {
        // 第一行内容
        setCellText(table.getRow(0).getCell(0), "姓 名", true);
        setCellText(table.getRow(0).getCell(2), "性 别", true);
        setCellText(table.getRow(0).getCell(4), "出生年月", true);

        // 第二行内容
        setCellText(table.getRow(1).getCell(0), "民 族", true);
        setCellText(table.getRow(1).getCell(2), "籍 贯", true);
        setCellText(table.getRow(1).getCell(4), "政治面貌", true);

        // 第四行内容
        setCellText(table.getRow(2).getCell(0), "身份证号", true);
        setCellText(table.getRow(2).getCell(4), "职称", true);

        // 第五行内容
        setCellText(table.getRow(3).getCell(0), "联系方式", true);
        setCellText(table.getRow(3).getCell(4), "意向岗位", true);
    }

    private static void mergeCellsForASZPersonalInfo(XWPFTable table, JsonNode jsonNode) {

        setCellText(table.getRow(0).getCell(1),jsonNode.get("candidateName").asText(),true);
        setCellText(table.getRow(0).getCell(3),jsonNode.get("gender").asText(),true);
        setCellText(table.getRow(0).getCell(5),jsonNode.get("birthDate").asText(),true);

        setCellText(table.getRow(1).getCell(1),jsonNode.get("ethnic").asText(),true);
        setCellText(table.getRow(1).getCell(3),jsonNode.get("nativePlace").asText(),true);
        setCellText(table.getRow(1).getCell(5),jsonNode.get("politicalStatus").asText(),true);

        TableUtil.mergeCellsHorizontally(table,2,1,3);
        setCellText(table.getRow(2).getCell(1),jsonNode.get("idNumber").asText(),true);
        setCellText(table.getRow(2).getCell(5),jsonNode.get("position").asText(),true);

        TableUtil.mergeCellsHorizontally(table,3,1,3);
        setCellText(table.getRow(3).getCell(1),jsonNode.get("mobile").asText(),true);
        setCellText(table.getRow(3).getCell(5),jsonNode.get("expectedPosition").asText(),true);
        TableUtil.mergeVertical(table, 0, 3, 6);
    }

    /**
     * 设置页面为A4大小
     * @param document Word文档对象
     */
    private static void setA4PageSize(XWPFDocument document) {
        CTSectPr sectPr = document.getDocument().getBody().addNewSectPr();
        if (!sectPr.isSetPgMar()){
            sectPr.addNewPgMar();
        }
        CTPageMar pgMar = sectPr.getPgMar();

        pgMar.setLeft(BigInteger.valueOf(300));
        pgMar.setRight(BigInteger.valueOf(300));
        CTPageSz pageSz = sectPr.addNewPgSz();
        pageSz.setW(BigInteger.valueOf(11906));  // A4宽度(21cm) in twentieths of a point
        pageSz.setH(BigInteger.valueOf(16838));  // A4高度(29.7cm) in twentieths of a point
        pageSz.setOrient(STPageOrientation.PORTRAIT);  // 纵向
    }

    /**
     * 创建文档标题
     * @param document Word文档对象
     * @param title 标题文本
     */
    private static void createTitle(XWPFDocument document, String title,int fontSize) {
        XWPFParagraph paragraph = document.createParagraph();
        paragraph.setAlignment(ParagraphAlignment.CENTER);

        XWPFRun run = paragraph.createRun();
        run.setText(title);
        run.setBold(true);
        run.setFontSize(fontSize);
        run.addBreak();  // 添加换行
    }

    /**
     * 为指定行设置列宽
     * @param row       表格行对象
     * @param widths    列宽数组（单位：dxa）
     */
    private static void setColumnWidths(XWPFTableRow row, int[] widths) {
        for (int i = 0; i < widths.length; i++) {
            XWPFTableCell cell = row.getCell(i);
            CTTcPr tcPr = cell.getCTTc().getTcPr();
            if (tcPr == null) tcPr = cell.getCTTc().addNewTcPr();

            CTTblWidth cellWidth = tcPr.isSetTcW() ? tcPr.getTcW() : tcPr.addNewTcW();
            cellWidth.setType(STTblWidth.DXA);
            cellWidth.setW(BigInteger.valueOf(widths[i]));
        }
    }
    /**
     * 创建个人信息表格
     * @param document Word文档对象
     */
    private static void createPersonalInfoTable(XWPFDocument document,JsonNode jsonNode) {
        // 创建6行16列的表格
        XWPFTable table = document.createTable(5, 7);
// 设置列宽（在初始化单元格之前）

        // 初始化所有单元格，防止null
        initializeTableCells(table, 4, 7);

        // 设置表格宽度为100%页面宽度
        table.setWidth("100%");
        // 设置列宽
        // 设置第一行的列宽（定义表格结构）
        setColumnWidths(table.getRow(0), columnWidths);
        // 设置所有行高为30磅
        for (XWPFTableRow row : table.getRows()) {
            row.setHeight(600); // 30磅 = 600 twips
        }
        // 合并单元格创建表头行
        mergeCellsForPersonalInfo(table,jsonNode);

        // 设置表格样式
        setTableBorders(table);

        // 填充个人信息表格内容
        fillPersonalInfoTable(table);
    }








    /**
     * 初始化表格单元格
     * @param table 表格对象
     * @param rows 行数
     * @param cols 列数
     */
    private static void initializeTableCells(XWPFTable table, int rows, int cols) {
        for (int i = 0; i < rows; i++) {
            XWPFTableRow row = table.getRow(i);
            if (row == null) {
                row = table.createRow();
            }
            for (int j = 0; j < cols; j++) {
                if (row.getCell(j) == null) {
                    row.createCell();
                }
            }
        }
    }

    /**
     * 合并个人信息表格的单元格
     * @param table 表格对象
     */
    private static void mergeCellsForPersonalInfo(XWPFTable table,JsonNode jsonNode) {
        // 第一行合并
        //  TableUtil.mergeCellsHorizontally(table, 0, 1, 3);   // 姓名后面的空白
        //    TableUtil.adjustMergedColumnWidth(table,0,1,600); //设置固定宽度
        setCellText(table.getRow(0).getCell(1),jsonNode.get("candidateName").asText(),true);
        //  TableUtil.mergeCellsHorizontally(table, 0, 4, 5);   // 性别标题
        //  TableUtil.adjustMergedColumnWidth(table,4,5,800);
        // TableUtil.mergeCellsHorizontally(table, 0, 6, 7);   // 性别空白

        // TableUtil.adjustMergedColumnWidth(table,6,7,800);
        setCellText(table.getRow(0).getCell(3),jsonNode.get("gender").asText(),true);
        //  TableUtil.mergeCellsHorizontally(table, 0, 8, 9);   // 出生年月标题
        // TableUtil.adjustMergedColumnWidth(table,8,9,600);
        //  TableUtil.mergeCellsHorizontally(table, 0, 10, 12); // 出生年月空白
        setCellText(table.getRow(0).getCell(5),jsonNode.get("birthDate").asText(),true);
        // TableUtil.adjustMergedColumnWidth(table,6,6,2800);
        // TableUtil.mergeCellsHorizontally(table, 0, 13, 15); // 照片位置

        // 第二行合并
        //  TableUtil.mergeCellsHorizontally(table, 1, 1, 3);   // 民族空白
        setCellText(table.getRow(1).getCell(1),jsonNode.get("ethnic").asText(),true);

//        TableUtil.mergeCellsHorizontally(table, 1, 4, 5);   // 籍贯标题
//        TableUtil.mergeCellsHorizontally(table, 1, 6, 7);   // 籍贯空白
        setCellText(table.getRow(1).getCell(3),jsonNode.get("nativePlace").asText(),true);

//        TableUtil.mergeCellsHorizontally(table, 1, 8, 9);   // 政治面貌标题
//        TableUtil.mergeCellsHorizontally(table, 1, 10, 12); // 政治面貌空白
        setCellText(table.getRow(1).getCell(5),jsonNode.get("politicalStatus").asText(),true);

        // TableUtil.mergeCellsHorizontally(table, 1, 13, 15); //  照片位置
        // 第三行合并
        // TableUtil.mergeCellsHorizontally(table, 2, 1, 3);   // 婚姻状况空白
        setCellText(table.getRow(2).getCell(1),jsonNode.get("marriageStatus").asText(),true);

//        TableUtil.mergeCellsHorizontally(table, 2, 4, 5);   // 职称标题
//        TableUtil.mergeCellsHorizontally(table, 2, 6, 7);   // 职称空白
        setCellText(table.getRow(2).getCell(3),jsonNode.get("position").asText(),true);

//        TableUtil.mergeCellsHorizontally(table, 2, 8, 9);   // 工作年限标题
//        TableUtil.mergeCellsHorizontally(table, 2, 10, 12); // 工作年限空白
        setCellText(table.getRow(2).getCell(5),jsonNode.get("workExperience").asText(),true);
        // TableUtil.mergeCellsHorizontally(table, 2, 13, 15); //  照片位置



////        // 合并前三行的第14列到第16列
//        for (int i = 0; i < 3; i++) {
//
//            TableUtil.mergeCellsHorizontally(table, i, 5, 6); // 合并第14列到第16列
//        }

        // 垂直合并三行的14列
        TableUtil.mergeVertical(table, 0, 2, 6);
//         TableUtil.adjustMergedColumnWidth(table,13,15,1800);
        // 第四行合并
        TableUtil.mergeCellsHorizontally(table, 3, 1, 3);   // 常驻地址空白
        setCellText(table.getRow(3).getCell(1),jsonNode.get("address").asText(),true);
        TableUtil.mergeCellsHorizontally(table, 3, 4, 4);   // 联系电话标题
        TableUtil.mergeCellsHorizontally(table, 3, 5, 6); // 联系电话空白
        setCellText(table.getRow(3).getCell(3),jsonNode.get("mobile").asText(),true);

        // 第五行合并
        TableUtil.mergeCellsHorizontally(table, 4, 1, 3);   // 身份证号空白
        setCellText(table.getRow(4).getCell(1),jsonNode.get("idNumber").asText(),true);
        TableUtil.mergeCellsHorizontally(table, 4, 4, 4);   // 业务方向标题
        TableUtil.mergeCellsHorizontally(table, 4, 5, 6); // 业务方向空白
        setCellText(table.getRow(4).getCell(3),jsonNode.get("business").asText(),true);
        // TableUtil.adjustMergedColumnWidth(table,13,15,1800);  TableUtil.adjustMergedColumnWidth(table,10,12,800);
        // 第六行合并为教育培训标题
        //  TableUtil.mergeCellsHorizontally(table, 5, 0, 6);
    }

    /**
     * 填充个人信息表格内容
     * @param table 表格对象
     */
    private static void fillPersonalInfoTable(XWPFTable table) {
        // 第一行内容
        setCellText(table.getRow(0).getCell(0), "姓 名", true);
        setCellText(table.getRow(0).getCell(2), "性 别", true);
        setCellText(table.getRow(0).getCell(4), "出 生\n年 月", true);

        // 第二行内容
        setCellText(table.getRow(1).getCell(0), "民 族", true);
        setCellText(table.getRow(1).getCell(2), "籍 贯", true);
        setCellText(table.getRow(1).getCell(4), "政 治\n面 貌", true);

        // 第三行内容
        setCellText(table.getRow(2).getCell(0), "婚姻状况", true);
        setCellText(table.getRow(2).getCell(2), "职 称", true);
        setCellText(table.getRow(2).getCell(4), "工作年限", true);

        // 第四行内容
        setCellText(table.getRow(3).getCell(0), "常驻地址", true);
        setCellText(table.getRow(3).getCell(4), "联系电话", true);

        // 第五行内容
        setCellText(table.getRow(4).getCell(0), "身份证号", true);
        setCellText(table.getRow(4).getCell(4), "业务方向", true);

        //  第六行内容 - 教育培训标题
        //setCellTextBold(table.getRow(5).getCell(0), "教育培训经历", true);
    } /**
     * 填充个人信息表格内容
     * @param table 表格对象
     */
    private static void fillPersonalInfoTable1(XWPFTable table) {
//        // 第一行内容
//        setCellText(table.getRow(0).getCell(0), "姓 名", true);
//        setCellText(table.getRow(0).getCell(2), "性 别", true);
//        setCellText(table.getRow(0).getCell(4), "出 生\n年 月", true);
//
//        // 第二行内容
//        setCellText(table.getRow(1).getCell(0), "民 族", true);
//        setCellText(table.getRow(1).getCell(2), "籍 贯", true);
//        setCellText(table.getRow(1).getCell(4), "政 治\n面 貌", true);
//
//        // 第三行内容
//        setCellText(table.getRow(2).getCell(0), "婚姻状况", true);
//        setCellText(table.getRow(2).getCell(2), "职 称", true);
//        setCellText(table.getRow(2).getCell(4), "工作年限", true);

        // 第四行内容
        setCellText(table.getRow(0).getCell(0), "常驻地址", true);
        setCellText(table.getRow(0).getCell(2), "联系电话", true);

        // 第五行内容
        setCellText(table.getRow(1).getCell(0), "身份证号", true);
        setCellText(table.getRow(1).getCell(2), "业务方向", true);

        // 第六行内容 - 教育培训标题
        setCellTextBold(table.getRow(2).getCell(0), "教育培训经历", true);
    }

    /**
     * 创建教育培训经历表格
     * @param document Word文档对象
     */
    private static void createEducationTable(XWPFDocument document,JsonNode jsonNode) {
        XWPFTable titleTable = document.createTable(1,7);
        initializeTableCells(titleTable, 1, 7);
        titleTable.setWidth("100%");
        XWPFTableRow titleTableRow = titleTable.getRow(0);
        setCellTextBold(titleTableRow.getCell(0), "教育培训经历", true);
        titleTableRow.setHeight(600);
        TableUtil.mergeCellsHorizontally(titleTable, 0, 0, 6);

        XWPFTable table = null;
        List<JsonNode> educationBackgroundList = new ArrayList<>();
        int rows = 2;
        if (jsonNode == null){
            table = document.createTable(2, 7);
        }else {
            Iterator<JsonNode> elements = jsonNode.elements();
            while (elements.hasNext()){
                educationBackgroundList.add(elements.next());
            }
            table = document.createTable(educationBackgroundList.size()+1, 7);
            rows = educationBackgroundList.size()+1;
        }
        // 创建教育培训表格 (3行16列)
        initializeTableCells(table, rows, 7);
        table.setWidth("100%");

        // 设置所有行高为30磅
        for (XWPFTableRow row : table.getRows()) {
            row.setHeight(600); // 30磅 = 600 twips
        }
        setTableBorders(table);
        // 第一行 - 表头
        setCellText(table.getRow(0).getCell(0), "开始时间", true);
        setCellText(table.getRow(0).getCell(1), "结束时间", true);
        setCellText(table.getRow(0).getCell(2), "机构名称", true);
        setCellText(table.getRow(0).getCell(3), "专业", true);
        setCellText(table.getRow(0).getCell(4), "学历", true);
        setCellText(table.getRow(0).getCell(5), "形式", true);
        setCellText(table.getRow(0).getCell(6), "备注", true);

//        // 合并单元格
//        TableUtil.mergeCellsHorizontally(table, 0, 0, 1);   // 开始时间
//        TableUtil.mergeCellsHorizontally(table, 0, 2, 3);   // 结束时间
//        TableUtil.mergeCellsHorizontally(table, 0, 4, 7);    // 机构名称
//        TableUtil.mergeCellsHorizontally(table, 0, 8, 8);    // 专业
//        TableUtil.mergeCellsHorizontally(table, 0, 9, 11);  // 学历
//        TableUtil.mergeCellsHorizontally(table, 0, 12, 13); // 形式
//        TableUtil.mergeCellsHorizontally(table, 0, 14, 15); // 备注

//        // 第二行 - 数据行
        for(int row = 1; row <rows; row++){
            JsonNode educationBackGround = educationBackgroundList.get(row-1);
            TableUtil.mergeCellsHorizontally(table, row, 0, 0);
            setCellText(table.getRow(row).getCell(0),educationBackGround.get("startDate").asText(),true);
            // TableUtil.mergeCellsHorizontally(table, row, 2, 3);
            setCellText(table.getRow(row).getCell(1),educationBackGround.get("endDate").asText(),true);
            //TableUtil.mergeCellsHorizontally(table, row, 4, 7);
            setCellText(table.getRow(row).getCell(2),educationBackGround.get("school").asText(),true);
            //TableUtil.mergeCellsHorizontally(table, row, 8, 8);
            setCellText(table.getRow(row).getCell(3),educationBackGround.get("major").asText(),true);
            // TableUtil.mergeCellsHorizontally(table, row, 9, 11);
            setCellText(table.getRow(row).getCell(4),educationBackGround.get("degree").asText(),true);
            // TableUtil.mergeCellsHorizontally(table, row, 12, 13);
            setCellText(table.getRow(row).getCell(5),educationBackGround.get("degreeType").asText(),true);
            // TableUtil.mergeCellsHorizontally(table, row, 14, 15);

            // 第三行 - 备注选项
            // TableUtil.mergeCellsHorizontally(table, row, 14, 15);
            XWPFParagraph para = table.getRow(1).getCell(6).getParagraphs().get(0);
            para.setAlignment(ParagraphAlignment.LEFT);

            XWPFRun run = para.createRun();
            run.setText("□ 就业学历");
            run.addBreak();
            run.setText("□ 最高学历");
            run.addBreak();
            run.setText("□ 职业资格");
        }
    }

    /**
     * 创建工作经历表格
     * @param document Word文档对象
     */
    private static void createWorkExperienceTable(XWPFDocument document,JsonNode jsonNode) {
        // 创建工作经历标题行
        XWPFTable titleTable = document.createTable(1, 1);
        initializeTableCells(titleTable, 1, 7);
        titleTable.setWidth("100%");
        XWPFTableRow titleTableRow = titleTable.getRow(0);
        setCellTextBold(titleTableRow.getCell(0), "工作经历", true);
        titleTableRow.setHeight(600);

        TableUtil.mergeCellsHorizontally(titleTable, 0, 0, 6);

        List<JsonNode> companiesNodeList = new ArrayList<>();
        XWPFTable table = null;
        int rows = 4;
        if (jsonNode == null || !jsonNode.elements().hasNext()){
            // 创建工作经历表格 (4行16列)
            table = document.createTable(rows, 7);
        }else {
            Iterator<JsonNode> elements = jsonNode.elements();
            while (elements.hasNext()){
                companiesNodeList.add(elements.next());
            }
            table = document.createTable(companiesNodeList.size()+1, 7);
            rows = companiesNodeList.size()+1;
        }

        initializeTableCells(table, rows, 7);
        table.setWidth("100%");
        // 设置所有行高为30磅
        for (XWPFTableRow row : table.getRows()) {
            row.setHeight(600); // 30磅 = 600 twips
        }
        setTableBorders(table);

        // 第一行 - 表头
        setCellText(table.getRow(0).getCell(0), "开始时间", true);
        setCellText(table.getRow(0).getCell(1), "结束时间", true);
        setCellText(table.getRow(0).getCell(2), "公司全称", true);
        setCellText(table.getRow(0).getCell(4), "部门", true);
        setCellText(table.getRow(0).getCell(6), "岗位/职位", true);

//        // 合并单元格
        TableUtil.mergeCellsHorizontally(table, 0, 0, 0);   // 开始时间
        TableUtil.mergeCellsHorizontally(table, 0, 1, 1);   // 结束时间
        TableUtil.mergeCellsHorizontally(table, 0, 2, 3);   // 公司全称
        TableUtil.mergeCellsHorizontally(table, 0, 4, 5); // 部门
        TableUtil.mergeCellsHorizontally(table, 0, 6, 6); // 岗位/职位

        // 数据行 (3行)
        if (CollectionUtils.isEmpty(companiesNodeList)){
            for (int i = 1; i <= 3; i++) {
                TableUtil.mergeCellsHorizontally(table, i, 0, 0);
                TableUtil.mergeCellsHorizontally(table, i, 1, 1);
                TableUtil.mergeCellsHorizontally(table, i, 2, 3);
                TableUtil.mergeCellsHorizontally(table, i, 4, 5);
                TableUtil.mergeCellsHorizontally(table, i, 6, 6);
            }
        }else {
            for (int i = 0; i < companiesNodeList.size(); i++) {
                int row = i + 1;
                JsonNode node = companiesNodeList.get(i);
                TableUtil.mergeCellsHorizontally(table, row, 0, 0);
                setCellText(table.getRow(row).getCell(0),node.get("startDate").asText(),true);
                TableUtil.mergeCellsHorizontally(table, row, 1, 1);
                setCellText(table.getRow(row).getCell(1),node.get("endDate").asText(),true);
                TableUtil.mergeCellsHorizontally(table, row, 2, 3);
                setCellText(table.getRow(row).getCell(2),node.get("companyName").asText(),true);
                TableUtil.mergeCellsHorizontally(table, row, 4, 5);
                setCellText(table.getRow(row).getCell(4),node.get("department").asText(),true);
                TableUtil.mergeCellsHorizontally(table, row, 6, 6);
                setCellText(table.getRow(row).getCell(6),node.get("position").asText(),true);

            }
        }
    }

    /**
     * 创建项目经验表格
     * @param document Word文档对象
     */
    private static void createProjectExperienceTable(XWPFDocument document,JsonNode jsonNode) {
        // 创建项目经验标题行
        XWPFTable titleTable = document.createTable(1, 1);
        initializeTableCells(titleTable, 1, 7);
        titleTable.setWidth("100%");
        XWPFTableRow titleTableRow = titleTable.getRow(0);
        setCellTextBold(titleTableRow.getCell(0), "项目经验", true);
        titleTableRow.setHeight(600);
        TableUtil.mergeCellsHorizontally(titleTable, 0, 0, 6);

        if (jsonNode == null || !jsonNode.elements().hasNext()){
            // 创建项目1表格 (3行16列)
            createSingleProjectTable(document, 1,null);
        }else {
            List<JsonNode> projectExperienceList = new ArrayList<>();
            Iterator<JsonNode> elements = jsonNode.elements();
            while (elements.hasNext()){
                projectExperienceList.add(elements.next());
            }
            for (int i = 1; i <= projectExperienceList.size(); i++) {
//                if (i <= 2){
                createSingleProjectTable(document,i,projectExperienceList.get(i-1));
//                }
            }
        }


        // 创建项目2表格 (3行16列)
//        createSingleProjectTable(document, 2);
    }

    /**
     * 创建单个项目表格
     * @param document Word文档对象
     * @param projectNumber 项目编号
     */
    private static void createSingleProjectTable(XWPFDocument document, int projectNumber, JsonNode jsonNode) {
        XWPFTable table = document.createTable(2, 7);
        initializeTableCells(table, 2, 7);
        table.setWidth("100%");
        // 设置所有行高为30磅
        for (XWPFTableRow row : table.getRows()) {
            row.setHeight(600); // 30磅 = 600 twips
        }
        setTableBorders(table);

        // 第一行 - 项目名称和时间
        setCellText(table.getRow(0).getCell(0), projectNumber + ".项目名称", true);
        setCellText(table.getRow(0).getCell(3), "进入项目时间", true);
        setCellText(table.getRow(0).getCell(5), "退出项目时间", true);

        // 合并单元格
        TableUtil.mergeCellsHorizontally(table, 0, 0, 0);   // 项目名称标题
        TableUtil.mergeCellsHorizontally(table, 0, 1, 2);   // 项目名称空白
        if (jsonNode != null){
            setCellText(table.getRow(0).getCell(1),jsonNode.get("projectName").asText(),true);
        }
        TableUtil.mergeCellsHorizontally(table, 0, 3, 3);   // 进入项目时间标题
        TableUtil.mergeCellsHorizontally(table, 0, 4, 4);  // 进入项目时间空白
        if (jsonNode != null){
            setCellText(table.getRow(0).getCell(4),jsonNode.get("startDate").asText(),true);
        }

        TableUtil.mergeCellsHorizontally(table, 0, 5, 5); // 退出项目时间标题
        TableUtil.mergeCellsHorizontally(table, 0, 6, 6); // 退出项目时间空白
        if (jsonNode != null){
            setCellText(table.getRow(0).getCell(6),jsonNode.get("endDate").asText(),true);
        }

        // 第二行 - 项目描述和工作职责
        setCellText(table.getRow(1).getCell(0), "项目描述", true);
        setCellText(table.getRow(1).getCell(2), "工作职责", true);

        // 合并单元格
        TableUtil.mergeCellsHorizontally(table, 1, 0, 0);   // 项目描述标题
        TableUtil.mergeCellsHorizontally(table, 1, 1, 2);   // 项目描述空白
        if (jsonNode != null){
            setCellText(table.getRow(1).getCell(1),jsonNode.get("projectDesc").asText(),true);
        }

        TableUtil.mergeCellsHorizontally(table, 1, 3, 3);   // 工作职责标题
        TableUtil.mergeCellsHorizontally(table, 1, 4, 6);  // 工作职责空白
        if (jsonNode != null){
            setCellText(table.getRow(1).getCell(4),jsonNode.get("duty").asText(),true);
        }

        // 第三行 - 空白行
        // TableUtil.mergeCellsHorizontally(table, 2, 0, 6);
    }

    /**
     * 添加公司核实声明
     * @param document Word文档对象
     */
    private static void addVerificationStatement(XWPFDocument document) {
        XWPFParagraph paragraph = document.createParagraph();
        paragraph.setAlignment(ParagraphAlignment.LEFT);
        paragraph.setSpacingAfter(400);  // 设置段后间距

        XWPFRun run = paragraph.createRun();
        run.setText("我公司已核实该应聘者简历上的个人信息，确保各项信息真实、准确、有效。");
        run.setFontSize(12);
    }


    /**
     * 设置单元格文本
     * @param cell 表格单元格
     * @param text 文本内容
     * @param center 是否居中
     */
    private static void setCellText(XWPFTableCell cell, String text, boolean center) {
        if (cell == null) {
            throw new IllegalArgumentException("单元格不能为null");
        }

        // 移除现有段落（如果有）
        while (cell.getParagraphs().size() > 0) {
            cell.removeParagraph(0);
        }

        XWPFParagraph para = cell.addParagraph();
        if (center) {
            para.setAlignment(ParagraphAlignment.CENTER);
//            para.setVerticalAlignment(TextAlignment.CENTER);

        }else {
            para.setAlignment(ParagraphAlignment.LEFT);
        }

        cell.setVerticalAlignment(XWPFTableCell.XWPFVertAlign.CENTER);
        XWPFRun run = para.createRun();
        String[] multiText = text.split("\n");
        for (int i = 0; i < multiText.length; i++) {
            run.setText(multiText[i]);
            if (i > 0){
                run.addBreak();
            }
        }

    }

    private static void appendCellText(XWPFTableCell cell,String text,boolean bold){
        XWPFParagraph para = cell.addParagraph();

        cell.setVerticalAlignment(XWPFTableCell.XWPFVertAlign.CENTER);
        XWPFRun run = para.createRun();
        String[] multiText = text.split("\n");
        for (int i = 0; i < multiText.length; i++) {
            run.setText(multiText[i]);
            run.setBold(bold);

            if (i != 0){
                run.addBreak();
            }
        }
    }

    private static void setCellTextBold(XWPFTableCell cell, String text, boolean center) {
        if (cell == null) {
            throw new IllegalArgumentException("单元格不能为null");
        }

        // 移除现有段落（如果有）
        while (cell.getParagraphs().size() > 0) {
            cell.removeParagraph(0);
        }

        XWPFParagraph para = cell.addParagraph();
        if (center) {
            para.setAlignment(ParagraphAlignment.CENTER);
//            para.setVerticalAlignment(TextAlignment.CENTER);

        }

        cell.setVerticalAlignment(XWPFTableCell.XWPFVertAlign.CENTER);
        XWPFRun run = para.createRun();
        run.setBold(true);
        run.setText(text);
    }

    private static void setCellTextBoldAndColor(XWPFTableCell cell, String text, boolean center,String color) {
        if (cell == null) {
            throw new IllegalArgumentException("单元格不能为null");
        }

        // 移除现有段落（如果有）
        while (cell.getParagraphs().size() > 0) {
            cell.removeParagraph(0);
        }

        XWPFParagraph para = cell.addParagraph();
        if (center) {
            para.setAlignment(ParagraphAlignment.CENTER);
//            para.setVerticalAlignment(TextAlignment.CENTER);

        }

        cell.setVerticalAlignment(XWPFTableCell.XWPFVertAlign.CENTER);
        cell.setColor(color);
        XWPFRun run = para.createRun();
        run.setBold(true);
        run.setText(text);
    }


    /**
     * 设置表格边框
     * @param table 表格对象
     */
    private static void setTableBorders(XWPFTable table) {
        CTTblPr tblPr = table.getCTTbl().getTblPr();
        CTTblBorders borders = tblPr.addNewTblBorders();
        borders.addNewBottom().setVal(STBorder.SINGLE);
        borders.addNewLeft().setVal(STBorder.SINGLE);
        borders.addNewRight().setVal(STBorder.SINGLE);
        borders.addNewTop().setVal(STBorder.SINGLE);
        borders.addNewInsideH().setVal(STBorder.SINGLE);
        borders.addNewInsideV().setVal(STBorder.SINGLE);
    }
}

/**
 * 表格工具类，提供合并单元格等方法
 */
class TableUtil {

    public static void adjustColumnWidth(XWPFTable table, int col, int width) {
        CTTblGrid grid = table.getCTTbl().getTblGrid();
        if (grid.sizeOfGridColArray() > col) {
            grid.getGridColArray(col).setW(BigInteger.valueOf(width));
        }
    }

    /**
     * 调整合并列的宽度
     * @param table 表格对象
     * @param fromCol 起始列
     * @param toCol 结束列
     * @param totalWidth 合并后的总宽度
     */
    public static void adjustMergedColumnWidth(XWPFTable table, int fromCol, int toCol, int totalWidth) {
        CTTblGrid grid = table.getCTTbl().getTblGrid();
        if (grid == null) return;

        int singleWidth = totalWidth / (toCol - fromCol + 1);
        for (int i = fromCol; i <= toCol; i++) {
            if (i < grid.sizeOfGridColArray()) {
                grid.getGridColArray(i).setW(BigInteger.valueOf(singleWidth));
            }
        }
    }

    /**
     * 水平合并单元格
     * @param table 表格对象
     * @param row 行索引
     * @param fromCol 起始列索引
     * @param toCol 结束列索引
     */
    public static void mergeCellsHorizontally(XWPFTable table, int row, int fromCol, int toCol) {
        if (table == null || row < 0 || fromCol < 0 || toCol >= 16) {
            throw new IllegalArgumentException("无效的表格参数");
        }

        XWPFTableRow tableRow = table.getRow(row);
        if (tableRow == null) {
            throw new IllegalArgumentException("行不存在: " + row);
        }

        // 确保列存在
        for (int colIndex = fromCol; colIndex <= toCol; colIndex++) {
            if (tableRow.getCell(colIndex) == null) {
                tableRow.createCell();
            }
        }

        for (int colIndex = fromCol; colIndex <= toCol; colIndex++) {
            XWPFTableCell cell = tableRow.getCell(colIndex);
            if (cell == null) {
                throw new IllegalStateException("单元格创建失败: 行" + row + ", 列" + colIndex);
            }

            if (colIndex == fromCol) {
                // 第一个单元格设置合并范围
                cell.getCTTc().addNewTcPr().addNewHMerge().setVal(STMerge.RESTART);
            } else {
                // 后续单元格标记为被合并
                cell.getCTTc().addNewTcPr().addNewHMerge().setVal(STMerge.CONTINUE);
            }
        }
    }
    /**
     * 垂直合并单元格
     * @param fromRow 起始行（包含）
     * @param toRow 结束行（包含）
     * @param col 目标列
     */
    public static void mergeVertical(XWPFTable table, int fromRow, int toRow, int col) {
        for (int row = fromRow; row <= toRow; row++) {
            XWPFTableCell cell = table.getRow(row).getCell(col);
            CTTcPr tcPr = cell.getCTTc().addNewTcPr();
            if (row == fromRow) {
                tcPr.addNewVMerge().setVal(STMerge.RESTART);
            } else {
                tcPr.addNewVMerge().setVal(STMerge.CONTINUE);
            }
        }
    }
}
